#!/usr/bin/perl

use strict;
use warnings;
use lib '/home/services/cbbot/irclib';
use lib '/home/services/cbbot/2.0/';
use feature qw(switch);
use CBBOT::Config;
use CBBOT::Server;
use CBBOT::Clanbase;
use CBBOT::AI;
use WWW::Mechanize;
use POE::Component::IRC;
use POE;

my $dbh	= CBBOT::Config::get_dbh();
my %config = %CBBOT::Config::config;
my $start_ts = time;
my $last_id = 0;
my %server;
my %challenge;

my $irc = POE::Component::IRC->spawn(
	nick   => $config{botnick},
	ircname => $config{ircname},
	server => $config{ircserver},
) or die("Couldn't spawn new IRC object: $!");

POE::Session->create(
	package_states => [
		main => [ qw(_start irc_001 irc_public autoping irc_join check_challenges) ],
	],
);

$poe_kernel->run();

sub _start {
	$irc->yield(register => 'all');
	$irc->yield(connect => { });
}

sub irc_001 {
	my($kernel, $heap) = @_[KERNEL, HEAP];
	my $sth = $dbh->prepare("SELECT channel FROM setup");
	$sth->execute();

	while(my @channel = $sth->fetchrow_array()) {
		$irc->yield(join => $channel[0]);
	}

	$kernel->delay(autoping => 60);
	$kernel->delay(check_challenges => 60);
}

sub irc_join {
	my ($sender, $who, $where) = @_[SENDER, ARG0, ARG1];
	my $nick = (split /!/, $who)[0];
}

sub irc_public {
	my ($sender, $who, $where, $what) = @_[SENDER, ARG0 .. ARG2];
	my $nick = (split /!/, $who)[0];
	my $channel = $where->[0];

	my %triggers = (
		"!rank" => \&CBBOT::Clanbase::clan_rank,
		"!last" => \&CBBOT::Clanbase::last_match,
		"!ts" => \&CBBOT::Server::voice_server,
		"!online" => \&CBBOT::Server::game_server,
		"!judge" => \&CBBOT::Clanbase::judge_clan,
		"!link" => \&CBBOT::Server::get_link,
		"!connect" => \&CBBOT::Server::get_link,
		"!intern" => \&CBBOT::Server::get_link,
	);

	if($what =~ /kylling/i) {
		#if($what =~ /kylling: ((\+|-)\d)/) {
		#	if($2 eq "+") {
		#		CBBOT::AI::upvote_reply($last_id);
		#		my $rating = CBBOT::AI::get_rating($last_id);
		#		$irc->yield(privmsg => $channel, "$nick: You upvoted me! (Debug: $last_id, r=$rating)");
		#	} elsif($2 eq "-") {
		#		CBBOT::AI::downvote_reply($last_id);
		#		my $rating = CBBOT::AI::get_rating($last_id);
		#		$irc->yield(privmsg => $channel, "$nick: You downvoted me! (Debug: $last_id, r=$rating)");
		#	}
		#} else {
		#	my @reply = CBBOT::AI::make_sense($what);
		#	$last_id = $reply[1];
		#	$irc->yield(privmsg => $channel, "$nick: $reply[0]");
		#}
		$irc->yield(privmsg => $channel, "$nick: AI-delen oppdateres, prøv igjen senere! ;-)");
	} else {
		while(my($key,$value) = each %triggers) {
			if($what =~ /$key/) {
				given($key) {
					when(/!rank/) {
						my $yield = $value->($what, $channel, 'withtext');
						$irc->yield(privmsg => $channel, $yield);
					}
					when(/!last/) {
						my $yield = $value->($what, $channel, 'withtext');
						$irc->yield(privmsg => $channel, $yield);
					}
					when(/!ts/) {
						my @yield = $value->($what, $channel);
						foreach my $y (@yield) {
							$irc->yield(privmsg => $channel, $y);
						}
					}
					when(/!online/) {
						my @yield = $value->($what, $channel, 'full');
						foreach my $y (@yield) {
							$irc->yield(privmsg => $channel, $y);
						}
					}
					when(/!judge/) {	
						my @yield = $value->($what, $channel);
						foreach my $y (@yield) {
							$irc->yield(privmsg => $channel, $y);
						}
					}
					when(/!link/) {
						my $ref = $dbh->selectrow_hashref("
							SELECT clanid, ladderid FROM setup WHERE channel=?", undef, $channel);
	
						$irc->yield(privmsg => $channel, 
							"http://clanbase.ggl.com/claninfo.php?wars=1&cid=$ref->{clanid}&lid=$ref->{ladderid}"
						);
					}
					when(/!connect/) {
						my $ref = $dbh->selectrow_hashref("
							SELECT gameserver, voiceserver FROM setup WHERE channel=?", undef, $channel);
	
						if(defined($ref)) {
							$irc->yield(privmsg => $channel, "connect $ref->{gameserver}; password $config{matchserverpwd}");
						} else {
							$irc->yield(privmsg => $channel, "No gameserver defined for this channel");
						}
					}
					when(/!intern/) {
						$irc->yield(privmsg => $channel, "connect $config{internserver}; password $config{internserverpwd}");
					}	
				}
			}
		}
	}
	return;
}

sub autoping {
	my($kernel, $heap) = @_[KERNEL, HEAP];
	my $channel = "#norsof.org";
	my($players, $new) = (0, 0);
	my $sql = "(SELECT gameserver FROM setup) UNION (SELECT internserver FROM setup)";
	my $sth = $dbh->prepare($sql);
	$sth->execute();
	my @status;

	while(my @servers = $sth->fetchrow_array()) {
		@status = CBBOT::Server::game_server("!online $servers[0]", $channel, "full");
		if(!exists($server{$servers[0]})) {
			$server{$servers[0]} = 0;
		}

		if(scalar(@status) > 0) {
			if($status[$#status] =~ /A\stotal\sof\s(\d+)\splayer/) {
				$players = $1;

				if($server{$servers[0]} == 0) {
					$irc->yield(privmsg => $channel, "$players online @ $servers[0]");
				} elsif($server{$servers[0]} < $players) {
					$new = $players - $server{$servers[0]};
					$irc->yield(privmsg => $channel, "$new joined $servers[0] ($players totalt)");
				}
				$server{$servers[0]} = $players;
	
			} elsif($server{$servers[0]} != 0 && $players == 0) {
				$irc->yield(privmsg => $channel, "Game over!");
				delete($server{$servers[0]});
			} else {
				my $runtime = time - $start_ts;
				if(int($runtime) > 10000) {
					open LOADAVG, "</proc/loadavg"
						or die "/proc/loadavg: $!";
					my $line = <LOADAVG>;
					close LOADAVG;
					$line =~ /^(\d+\.\d+) / or print "Couldn't parse /proc/loadavg";
					my $loadavg = $1;	
					$start_ts = time;
				}
			}
		}
		@status = ();
	}
	$kernel->delay(autoping => 60);
}

sub check_challenges {
	my($kernel, $heap) = @_[KERNEL, HEAP];
	my @return = "";
	my $channel = "#norsof.org";
	my $sql = "SELECT clanid, voiceserver FROM setup";
	my $sth = $dbh->prepare($sql);
	$sth->execute();

	if($sth->rows > 0) {
		while(my @row = $sth->fetchrow_array()) {
		 	my $user = $config{cbmail};
	        my $pass = $config{cbpass};
	        my $url  = $config{cbloginurl};
   		    my $ua = WWW::Mechanize->new();

	        $ua->cookie_jar(
            	HTTP::Cookies->new(
                	file => "$CBBOT::Config::home/cookies.txt",
                	autosave => 1,
                	ignore_discard => 1,
				)
			);

            if($ua->get($url)) {
            	$ua->form_number(1);
            	$ua->field('email', $user);
            	$ua->field('password', $pass);
            	$ua->submit();
            	$ua->get("http://clanbase.ggl.com/claninfo.php?cid=$row[0]");
				my $html = $ua->content();
				
				if($html =~ /Next\sWar:\s<a\shref="\/warinfo\.php\?wid=(\d+)/ig) {
					my $warid = $1;
					if(!exists($challenge{$warid})) {
						$challenge{$warid} = 1;
						push(@return, "New challenge accepted!");
						push(@return, "TZAC: $warid");
	
						$ua->get("http://clanbase.ggl.com/warinfo.php?wid=$warid");
						$html = $ua->content();
						if($html =~ /mp_(\w+)\/mp_(\w+)/ig) {
							push(@return, "Maps: $1 / $2");
						} 
						if($html =~ /(\d+\.\d+\.\d+\.\d+):(\d+)\s\(<span\sclass='labelcell3'>password:<\/span>\s(.*?)\)<\/td><\/tr>/) {
							push(@return, "connect $1:$2; password $3");
						} else {
							push(@return, "Server could not be fetched");
						}
					
						foreach my $y (@return) {
							$irc->yield(privmsg => $channel, $y);	
						}
						
						CBBOT::Server::notify_voice(\@return, $row[1]);
					}
				}
			}
		}
	}

	$kernel->delay(check_challenges => 60);
}

